package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"strconv"
	"syscall"
	"time"
)

// Config config items
type Config struct {
	Mode string
}

func loadConfig() error {

	f, err := ioutil.ReadFile("config.json")
	if err != nil {
		return err
	}

	return json.Unmarshal(f, &config)
}

var (
	config *Config
	cmd    string // start || reload
)

func init() {
	if len(os.Args) < 2 {
		cmd = "start"
	} else {
		cmd = os.Args[1]
	}
}

func main() {
	if cmd == "start" {
		start()
	} else if cmd == "reload" {
		reload()
	} else {
		log.Panicf("unknow command %s\n", cmd)
	}
}

func start() {
	savePid()

	if err := loadConfig(); err != nil {
		panic(err)
	}

	// register signal handler
	{
		s := make(chan os.Signal, 1)
		signal.Notify(s, syscall.SIGUSR2)

		go func() {
			for {
				<-s
				fmt.Println("[Info] trigger reload config")
				if err := loadConfig(); err != nil {
					fmt.Printf("[Error] reload config error, err: %s\n", err.Error())
				}
			}
		}()
	}

	for {
		time.Sleep(2 * time.Second)
		fmt.Printf("mode: %s\n", config.Mode)
	}
}

func reload() {
	pid, err := getPid()
	if err != nil {
		log.Printf("get pid failed, err: %s\n", err.Error())
	}
	cmd := exec.Command("kill", "-USR2", pid)
	cmd.Run()
}

func savePid() error {
	p := os.Getpid()
	pStr := strconv.Itoa(p)
	return ioutil.WriteFile("pid", []byte(pStr), 0755)
}

func getPid() (string, error) {
	buf, err := ioutil.ReadFile("pid")
	return string(buf), err
}
